const { JJCourseRefundRate, JJUserOrder, JJCourseRefundOrder, JJCourseCamp, JJCourse,
  JJCourseAccountBill, Ctcdb, JJUserCourse, JJCourseRefundApply, JJUserAccountBill, JJCourseCommission } = require('../../models/ctcdb');
const BaseResp = require('../../utils/baseResp');
const errorCode = require('../../utils/errorCode');
const SequenceUtil = require('../../utils/sequece');
const moment = require('moment');
const WxPay = require('../../utils/wxPay');
const tools = require('../../utils/tools');

async function getRecentRefundRateByTime(time) {
  const rates = await JJCourseRefundRate.findAll({
    where: {
      time: {
        $gte: time
      }
    },
    order: [['time', 'desc']],
    attributes: ['time', 'percent', 'type'],
    raw: true
  });
  let percent = 0;
  rates.forEach((item) => {
    if (item.type === 1 && item.time > time) {
      throw BaseResp.error(errorCode.COURSE.CAN_NOT_REFUND)
    }
    if (item.type === 2 && item.time > time) {
      percent = item.percent
    }
  });
  return percent;
}

async function refundSigleByRate({ rate, orderId, refundTotalSum, deductTotalSum, type }) {
  console.log('.....type...is...', type)
  const order = await JJUserOrder.findOne({
    where: {
      id: orderId
    },
    attributes: ['orderNo', 'jUserId', 'id', 'jUserId', 'price', 'courseId', 'lUserId'],
    raw: true
  });
  if (!order) {
    throw BaseResp.error(errorCode.ORDER.NOT_FOUND)
  }
  const { jUserId, orderNo, price, courseId, lUserId } = order;
  let deductSum = price * (rate/100);
  let refundSum = price - deductSum ; // 应该退款金额
  let duductPercent = 0.95;
  if (refundTotalSum) {
    refundSum = refundTotalSum; // 如果知道实际退款金额直接以金额为准
  }
  if (deductTotalSum > 0) {
    const info = await JJCourseCommission.findOne({
      where: {
        type
      },
      attributes: ['percent'],
      raw: true
    });
    if (info) {
      duductPercent = info.percent / 100
    }
    deductSum = deductTotalSum;
  }
  console.log('this is self courese off', deductSum);
  console.log('this is self courese percent', duductPercent);
  // console.log(deductSum)
  const outRefundNo = await SequenceUtil.getWxRefundId();
  // const outRefundNo = 're_20190716000685';
  const refundOrder = await JJCourseRefundOrder.create({
    refundNo: outRefundNo,
    refundPrice: refundSum,
    orderId: orderId,
    jUserId,
    status: 0
  });
  return new Promise((resolve, reject) => {
    const wxPay = new WxPay();
    const refundWxFee = parseInt(refundSum * 100);
    const totalFee = parseInt(price * 100);
    return wxPay.refund({
      transaction_id: orderNo,
      out_refund_no: outRefundNo,
      refund_fee: refundWxFee,
      total_fee: totalFee
    }, async function (err, data) {
      if (err) {
        return reject(err)
      }
      if (data.return_code === 'SUCCESS' && data.return_msg === 'OK' && data.result_code === 'SUCCESS') {
        // const t = await Ctcdb.transaction();
        const wxRefundNo = data.refund_id;
        await JJCourseRefundOrder.update({
          wxRefundNo,
          status: 1
        }, {
          where: {
            id: refundOrder.id
          }
        });
        // fixme 这里应该减去这个订单所有的的金额(应该是整个订单的金额)
        const sql = `update jj_course_account set balance = balance - ${ price } where jj_course_id = ${courseId}`;
        await Ctcdb.query(sql);
        await JJCourseAccountBill.create({
          amount: -price,
          type: 1,
          remark: `用户退款`,
          jUserId,
          courseId
        });
        // 课程变成用户自定义取消状态
        await JJUserCourse.update({
          // status: -1,
          state: -1
        }, {
          where: {
            jUserId,
            courseId
          }
        });
        await JJUserOrder.update({
          refundNo: outRefundNo,
          wxRefundNo: wxRefundNo,
          refundPrice: refundSum
        }, {
          where: {
            id: orderId
          }
        });
        // 说明有违约金
        if (deductSum > 0) {
          // todo 给教练加钱
          // 增加教练账户余额，这个值是可以进行变动的
          deductSum = tools.dealNumberTwo(deductSum * duductPercent);
          console.log(deductSum);
          let addSql = `update jj_user_account set balance=balance+${deductSum} where ref_jj_user_id=${lUserId}`;
          await Ctcdb.query(addSql);
          await JJUserAccountBill.create({
            userId: lUserId,
            type: 'COURSE_REFUND_ADD',
            courseId,
            amount: deductSum,
            remark: '退款违约金'
          });
        }
        return resolve()
      } else {
        console.log(data);
        return reject(data.err_code_des || data.return_msg)
      }
    })
  })
}

/**
 * 退款未开始的团课
 * @param rate // 退款比例
 * @param orderId
 * @returns {Promise}
 */
async function refundNotStartBigCourse({ rate, orderId, type }) {
  await refundSigleByRate({ rate, orderId, type });
}

/**
 * 退款未开始的训练营
 * @param rate // 退款比例
 * @param orderId
 * @returns {Promise}
 */
async function refundNotStartCamp({ rate, orderId, type }) {
  // 未开始的时候，和团课一模一样的退款
  await refundSigleByRate({ rate, orderId, type })
}

/**
 * 退款私人定制的课程
 * @param courseId 课程Id
 * @param userId 用户Id
 * @returns {Promise<void>}
 */
async function refundMakeCourse({ courseId, userId, type }) {
  const [camps, userCourse, refundRateInfo] = await Promise.all([
    // 查询所有的课时
    JJCourseCamp.findAll({
      where: {
        courseId
      },
      attributes: ['cStatus'],
      raw: true
    }),
    // 查询所有的用户已经上过的课时
    JJUserCourse.findOne({
      where: {
        state: 1,
        courseId,
        jUserId: userId,
        type: 1
      },
      attributes: ['id', 'orderId'],
      raw: true
    }),
    JJCourseRefundRate.findOne({
      where: {
        type: 3
      },
      attributes: ['time', 'percent'],
      raw: true
    })
  ]);
  if (!userCourse) {
    throw BaseResp.error(500, '此课程状态不对')
  }
  const { orderId } = userCourse;
  const num = camps.length;
  if (num === 0) {
    // 如果一个课程都没有 说明还没有开始定制课程直接退款全部
    return refundSigleByRate({ orderId, rate: 0, type });
  }
  const order = await JJUserOrder.findOne({
    where: {
      id: orderId
    },
    attributes: ['orderNo', 'jUserId', 'id', 'jUserId', 'price', 'courseId'],
    raw: true
  });
  if (!order) {
    throw BaseResp.error(errorCode.ORDER.NOT_FOUND)
  }
  const { price } = order;
  let useCampNum = 0;
  camps.forEach((item) => {
    // 说明这节课时已经结束
    if (item.cStatus === 10) {
      useCampNum += 1
    }
  });
  let point = 2;
  let makeRate = 0.2;
  if (refundRateInfo) {
    point = refundRateInfo.time;
    makeRate = refundRateInfo.percent / 100
  }
  const campPoint = useCampNum;
  let refundSum = 0;
  let deductTotalSum = price/num * useCampNum;
  if (point > campPoint) {
    refundSum = tools.dealNumberTwo(Number((price - deductTotalSum)))
  } else {
    deductTotalSum += price * makeRate;
    refundSum = tools.dealNumberTwo(Number((price - deductTotalSum)))
  }
  await refundSigleByRate({ orderId, refundTotalSum: refundSum, deductTotalSum, type });
  await JJCourse.update({
    status: -1
  }, {
    where: {
      id: courseId
    }
  })
}

async function refundNormalCourse({ orderId, type }) {
  await refundSigleByRate({ orderId, rate: 0, type })
}

/**
 * 创建初始的退款申请单
 * @param courseId
 * @param applyUserId 申请人用户Id
 * @param handleUserId 处理人Id
 * @param type
 * @returns {Promise<void>}
 */
async function createRefundApply({ courseId, applyUserId, handleUserId, type, remark }) {
  await JJCourseRefundApply.create({
    courseId,
    applyUserId,
    handleUserId,
    type,
    status: 0,
    refundStatus: 0,
    remark
  })
}

module.exports = {
  // 退款没开始的团课
  refundNotStartBigCourse,
  // 退款训练营
  refundNotStartCamp,
  // 退款私人订制的私教
  refundMakeCourse,
  // 退款正常的私教
  refundNormalCourse,
  // 根据时间获取费率
  getRecentRefundRateByTime,
  // 发起退款申请
  createRefundApply
};
